package tool.zyk.spring.bean;

import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.*;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import tool.zyk.spring.annotation.RpcProvider;

/**
 * @author feite.zyk
 * @time 2024/2/2 15:20
 * @description RPC注入器
 */
@Slf4j
@Getter
@Setter
public class RpcInjector implements BeanDefinitionRegistryPostProcessor {

    private String basePackage;


    @SneakyThrows
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        log.info("bingo");

        CachingMetadataReaderFactory cachingMetadataReaderFactory = new CachingMetadataReaderFactory();
        BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();//bean名字生成器
        String path = "classpath*:" + basePackage.replace(".", "/") + "/**/*.class";
        Resource[] resources = new PathMatchingResourcePatternResolver().getResources(path);
        for (Resource resource : resources) {
            MetadataReader metadataReader = cachingMetadataReaderFactory.getMetadataReader(resource);
            AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
            //如果有这个注解  那么就注册到 注册中心
            if (annotationMetadata.hasAnnotation(RpcProvider.class.getName())) {
                AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(metadataReader.getClassMetadata().getClassName()).getBeanDefinition();
                String beanName = beanNameGenerator.generateBeanName(beanDefinition, beanDefinitionRegistry);
                beanDefinitionRegistry.registerBeanDefinition(beanName, beanDefinition);
            }
        }


    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        // do nothing
    }
}
